// Copyright 2019 The rhyme_lph Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// p [author] rhyme_lph
// V [email]  rhymelph@gmail.com
// V [github] https://github.com/rhymelph

import 'package:base_plugin/base_plugin.dart';
import 'package:finance_app/generated/l10n.dart';
import 'package:finance_app/src/common/config.dart';
import 'package:finance_app/src/entities/company_entity.dart';
import 'package:finance_app/src/entities/current_subscription_entity.dart';
import 'package:finance_app/src/entities/plans_subscription_entity.dart';
import 'package:finance_app/src/entities/sub_billing_item_entity.dart';
import 'package:finance_app/src/entities/suggest_date_entity.dart';
import 'package:finance_app/src/http_service/http_company_service.dart';
import 'package:finance_app/src/http_service/http_setting_service.dart';
import 'package:finance_app/src/http_service/http_subscription_service.dart';
import 'package:finance_app/src/provider/dashboard/dashboard_view_provider.dart';
import 'package:finance_app/src/provider/dashboard_provider.dart';
import 'package:finance_app/src/provider/setting/subscription/sub_billing_provider.dart';
import 'package:finance_app/src/provider/setting/subscription/sub_plans_provider.dart';
import 'package:finance_app/src/router_gen/override_route_providers.dart';
import 'package:finance_app/src/router_gen/router_gen_providers.dart';
import 'package:finance_app/src/utils/date_time_utils.dart';
import 'package:finance_app/src/widgets/bottom_sheet/got_it_info_bottom_sheet.dart';
import 'package:finance_app/src/widgets/bottom_sheet/judge_bottom_sheet.dart';
import 'package:flutter/material.dart';

class SubscriptionProvider extends BaseProvider<PlansSubscriptionEntity> {
  List<String> tabs = [
    S.current.billing,
    S.current.plans,
  ];
  TabController controller;
  bool isShowBill = false;

  List<CompanyEntity> companies;

  List<String> menuList = ['Manage Default Card'];

  @override
  Future get dataFuture =>
      HttpSubscriptionService.getSubscriptionsPlans(type: 'monthly');

  @override
  List<BaseProvider> registerChildProviders() {
    return [
      SubBillingProvider(),
      SubPlansProvider(),
    ];
  }

  @override
  FutureOr<PlansSubscriptionEntity> transformData(
      PlansSubscriptionEntity d, bool isCache) async {
    // int index = d.plans.indexWhere(
    //     (element) => element.id == Config.currentSubscription.plan.id);
    // if (index > 0) {
    //   d.plans.removeRange(0, index);
    // }
    getChildProvider<SubPlansProvider>().monthlyList = d.plans;
    getChildProvider<SubPlansProvider>().topContents = d.topContents;

    for (final item in d.plans) {
      if (item.name == 'starting' && item.isCurrentSubscribed == 1) {
        isShowBill = false;
      }
    }
    await _loadAnnually();
    await loadCurrentSubscription();
    await _loadUnPaid();
    await _loadAvailableCompany();

    return super.transformData(d, isCache);
  }

  Future<void> _loadAvailableCompany() async {
    await post(HttpCompanyService.companyList(), onSuccess: (result) async {
      companies = getEntityFromResult<List<CompanyEntity>>(result);
    });
    if (companies == null) {
      companies = [];
    }
  }

  void onChangeCompany(int companyID) async {
    CompanyEntity company =
        companies.firstWhere((element) => element.id == companyID);
    RProvider.myProvider.globalMap[ConfigKey.currentCompany] = company;
    Config.userProfile.defaultCompanyId = company.id.toString();
    loadCurrentSubscription();
    DashboardProvider dashboard;

    dashboard = Config.dashboardProvider;
    if (dashboard != null) {
      dashboard.onRefreshDashboard();
      dashboard.getFinancialYears();
    }
    await RProvider.myProvider.updateGlobalMap();
    onTry();
  }

  Future<void> _loadAnnually() async {
    await post(
        HttpSubscriptionService.getSubscriptionsPlans(
          type: 'yearly',
        ),
        autoHandler: AutoHandler.Toast, onSuccess: (result) {
      PlansSubscriptionEntity d =
          getEntityFromResult<PlansSubscriptionEntity>(result);
      // int index = d.plans.indexWhere(
      //     (element) => element.id == Config.currentSubscription.plan.id);
      // if (index > 0) {
      //   d.plans.removeRange(0, index);
      // }
      getChildProvider<SubPlansProvider>().annuallyList = d.plans;
    });
  }

  Future<void> loadCurrentSubscription() async {
    await post(HttpSubscriptionService.getCompaniesSubscription(),
        autoHandler: AutoHandler.Toast, onSuccess: (result) async {
      CurrentSubscriptionEntity entity =
          getEntityFromResult<CurrentSubscriptionEntity>(result);
      RProvider.myProvider.globalMap[ConfigKey.currentSubscription] = entity;
      if (entity.plan.id > 1 && entity.subscription.renew != 1) {
        menuList.add('Cancel Subscription');
        update();
      } else {
        menuList.remove('Cancel Subscription');
        update();
      }
      await RProvider.myProvider.updateGlobalMap();
    });
  }

  Future<void> _loadUnPaid() async {
    SuggestDateEntity suggestDateEntity;
    await post(HttpSettingService.getSuggestTime(null), onSuccess: (result) {
      suggestDateEntity = getEntityFromResult<SuggestDateEntity>(result);
    });

    await post(HttpSubscriptionService.getSubCompanies(),
        autoHandler: AutoHandler.Toast, onSuccess: (result) async {
      List<SubBillingItemEntity> upcomingBillList = getEntityFromResult(result);
      if (upcomingBillList.length > 0) {
        isShowBill = true;
        update();
      }
      upcomingBillList.forEach((element) {
        element.currentDate = suggestDateEntity.systemDate;
      });

      getChildProvider<SubBillingProvider>().setUpcomingBills(upcomingBillList);
    });
  }

  void onSelectMenu(String value) {
    switch (value) {
      case 'Cancel Subscription':
        onCancelSubscription();
        break;
      case 'Manage Default Card':
        onNavigateManageCard();
        break;
    }
  }

  void onCancelSubscription() {
    obtainContext?.call((context) async {
      bool isSuccess = await showCancelSubscriptionBottomSheet(context);
      if (isSuccess == true) {
        isSuccess = false;
        await post(HttpSubscriptionService.cancelSubscription(),
            autoHandler: AutoHandler.Toast,
            loadingTip: S.current.loading, onSuccess: (result) {
          isSuccess = true;
        });
        if (isSuccess == true) {
          await showCancelSubscriptionSuccessBottomSheet(
              context,
              DateTimeUtils.formatGlobalDateTime(DateTimeUtils.toDateTime(
                  Config.currentSubscription.subscription.endAt,
                  'yyyy-MM-dd HH:mm:ss')));
          onTry();
        }
      }
    });
  }

  void onNavigateManageCard() {
    Routes.navigateTo(RouterGenProviders.subPaymentMethodManagerPage);
  }
}
